#pragma once
class Mesh;
class Skeleton;
class Serializer;
struct MeshData;
struct VertexDataBuff;
#include <vector>

class MeshSerializer
{
	enum MeshChunkID {
        M_HEADER							= 0x1000,
        M_MESH								= 0x3000,
		M_SUBMESH							= 0x4000,
		M_SUBMESH_OPERATION					= 0x4010,
		M_SUBMESH_BONE_ASSIGNMENT			= 0x4100,
		M_SUBMESH_TEXTURE_ALIAS				= 0x4200,
		M_GEOMETRY							= 0x5000,
		M_GEOMETRY_VERTEX_DECLARATION		= 0x5100,
		M_GEOMETRY_VERTEX_ELEMENT			= 0x5110,
		M_GEOMETRY_VERTEX_BUFFER			= 0x5200,
		M_GEOMETRY_VERTEX_BUFFER_DATA		= 0x5210,
		M_MESH_SKELETON_LINK				= 0x6000,
		M_MESH_BONE_ASSIGNMENT				= 0x7000,
		M_MESH_LOD							= 0x8000,
		M_MESH_LOD_USAGE					= 0x8100,
		M_MESH_LOD_MANUAL					= 0x8110,
		M_MESH_LOD_GENERATED				= 0x8120,
		M_MESH_BOUNDS						= 0x9000,
		M_SUBMESH_NAME_TABLE				= 0xA000,
		M_SUBMESH_NAME_TABLE_ELEMENT		= 0xA100,
		M_EDGE_LISTS						= 0xB000,
		M_EDGE_LIST_LOD						= 0xB100,
		M_EDGE_GROUP						= 0xB110,
		M_POSES								= 0xC000,
		M_POSE								= 0xC100,
		M_POSE_VERTEX						= 0xC111,
		M_ANIMATIONS						= 0xD000, 
		M_ANIMATION							= 0xD100,
		M_ANIMATION_TRACK					= 0xD110,
		M_ANIMATION_MORPH_KEYFRAME			= 0xD111,
		M_ANIMATION_POSE_KEYFRAME			= 0xD112,
		M_ANIMATION_POSE_REF				= 0xD113,
		M_TABLE_EXTREMES					= 0xE000,
		// new version.
		M_GEOMETRY_NORMALS					= 0x5100,
		M_GEOMETRY_COLOURS					= 0x5200,
		M_GEOMETRY_TEXCOORDS				= 0x5300,
    };

    enum SkeletonChunkID {
        SKELETON_HEADER						= 0x1000,
        SKELETON_BONE						= 0x2000,
        SKELETON_BONE_PARENT				= 0x3000,
        SKELETON_ANIMATION					= 0x4000,
		SKELETON_ANIMATION_TRACK			= 0x4100,
		SKELETON_ANIMATION_TRACK_KEYFRAME	= 0x4110,
		SKELETON_ANIMATION_LINK				= 0x5000
    };

public:
	MeshSerializer();
	~MeshSerializer();

	bool ImportMesh(const std::string& fileName, Mesh* mesh);
	bool ImportSkeleton(const std::string& fileName, Skeleton* skeleton);

private:
	bool readFileHeader(Serializer& ser, const char* version);
	WORD readChunk(Serializer& ser);

	// mesh reader...
	bool readMesh(Serializer& ser, MeshData& meshData);
	bool readGeometry(Serializer& ser, VertexDataBuff& vertexDataBuff);
	bool readSubMesh(Serializer& ser, MeshData& meshData);
	bool readSkeletonLink(Serializer& ser, MeshData& meshData);
	bool readMeshBoneAssignment(Serializer& ser, MeshData& meshData);
	bool readMeshLodInfo(Serializer& ser, MeshData& meshData);
	bool readBoundsInfo(Serializer& ser, MeshData& meshData);

	// skeleton reader..
	bool readBone(Serializer& ser, Skeleton* skeleton);
	bool readBoneParent(Serializer& ser, Skeleton* skeleton);
	bool readAnimation(Serializer& ser, Skeleton* skeleton);

private:
	std::string mVersion;
	const char* mMeshSerializerVersion;
	const char* mSkeletonSerializerVersion;
	DWORD mCurrentstreamLen;
};
